import { Server, Socket } from 'socket.io';
import { Room } from './Room';
import { Player } from './Player';
import { logger } from '../utils/logger';

export class Game {
	constructor(public io: Server) {}
	private rooms: Record<string, Room> = {};
	private players: Record<string, Player> = {};
	private roomIdByPlayerId: Record<string, string> = {};

	/**
	 * 往游戏中添加一个新房间
	 * @param roomId 房间ID
	 * @param owner 房主
	 * @returns
	 */
	addRoom(roomId: string, owner: string = ''): void {
		if (this.rooms[roomId]) return;
		this.rooms[roomId] = new Room(this, roomId, owner);
		logger.info(`AddRoom: ${roomId} ${owner}`);
	}

	/**
	 * 删除房间
	 * @param roomId
	 * @returns
	 */
	deleteRoom(roomId: string): void {
		if (!this.rooms[roomId]) return;
		Object.values(this.rooms[roomId].depts).forEach((dept) => {
			if (dept.isAI) dept.ai.clear();
		});
		delete this.rooms[roomId];
		logger.info(`DeleteRoom: ${roomId}`);
	}

	/**
	 * 往游戏里面添加一个玩家
	 * @param playerId
	 * @param socket
	 * @returns
	 */
	addPlayer(playerId: string, socket: Socket): void {
		if (this.players[playerId]) return;
		this.players[playerId] = new Player(playerId, socket);
		logger.info(`AddPlayer: ${playerId}`);
	}

	/**
	 * 加入房间
	 * @param roomId
	 * @param playerId
	 * @returns
	 */
	joinRoom(roomId: string, playerId: string): void {
		const room = this.rooms[roomId];
		const player = this.players[playerId];
		if (!room || !player) return;
		this.roomIdByPlayerId[playerId] = roomId;
		const socket = player.getSocket();
		if (socket) {
			// 加入房间
			socket.join(roomId);
			// 更新房间数据
			room.updateData();
			socket.emit('initRoom');
			room.send('roomUpdate', {});
		}
		logger.info(`JoinRoom: ${roomId} ${playerId}`);
	}

	/**
	 * 设置玩家名称
	 * @param playerId
	 * @param name
	 * @returns
	 */
	setPlayerName(playerId: string, name: string): void {
		const player = this.players[playerId];
		if (!player) return;
		player.setName(name);
	}

	/**
	 * 根据玩家ID获取房间ID
	 * @param playerId
	 * @returns
	 */
	getRoomByPlayerId(playerId: string): Room | undefined {
		const roomId = this.roomIdByPlayerId[playerId];
		return this.rooms[roomId];
	}

	/**
	 * 离开房间
	 * @param playerId
	 * @returns
	 */
	leaveRoom(playerId: string): void {
		const room = this.getRoomByPlayerId(playerId);
		if (!room) return;
		// 删除玩家痕迹
		for (const deptId in room.depts) {
			const dept = room.depts[deptId];
			if (dept.playerId == playerId) {
				dept.playerId = deptId;
				dept.isAI = true;
			}
		}

		logger.info(`LeaveRoom: ${playerId}`);
		delete this.roomIdByPlayerId[playerId];
		room.updateData();
		// 删除空闲房间
		let count = 0;
		for (const deptId in room.depts) {
			const dept = room.depts[deptId];
			if (!dept.isAI && dept.playerId != '') count++;
		}
		if (count == 0) this.deleteRoom(room.roomId);
	}

	/**
	 * 获取玩家名称
	 * @param playerId
	 * @returns
	 */
	getPlayerName(playerId: string): string | undefined {
		const player = this.players[playerId];
		if (!player) return;
		return player.getName();
	}

	/**
	 * 获取玩家Socket
	 * @param playerId
	 * @returns
	 */
	getPlayerSocket(playerId: string) {
		const player = this.players[playerId];
		if (!player) return;
		return player.getSocket();
	}
}
